package com.xuecheng.content.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.basic.api.BasicClient;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.vo.CategoryVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioTemplate;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.CoursePub;
import com.xuecheng.content.domain.CourseTeacher;
import com.xuecheng.content.mapper.CoursePubMapper;
import com.xuecheng.content.service.*;
import com.xuecheng.web.exception.BusinessException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import io.minio.errors.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author HuangYuwu
 * @since 2022-09-11
 */
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {

    @Autowired
    private TeachplanService teachplanService;
    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private CourseTeacherService courseTeacherService;
    @Autowired
    private BasicClient basicClient;
    @Autowired
    private PubPageService pubPageService;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 课程发布预览 TODO
     *
     * @param courseBaseId
     * @return
     */
    @Override
    public Map preview(Long courseBaseId) {
        ResponseResult<TeachplanVo> result = teachplanService.treeNodes(courseBaseId);
        TeachplanVo teachplanVo = result.getData();
        Map map = new HashMap<>();
        map.put("teachplanNode", teachplanVo);
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        CoursePub coursePub = BeanHelper.copyProperties(courseBase, CoursePub.class);
        BigDecimal price = courseBase.getPrice().multiply(BigDecimal.valueOf(100)); //TODO 价格转为以分为单位
        coursePub.setPrice(price.longValue());

        String mt = courseBase.getMt();
        String st = courseBase.getSt();
        ResponseResult<CategoryVo> mtResult = basicClient.findCourseById(mt);
        CategoryVo mtCategoryVo = mtResult.getData();
        String mtName = mtCategoryVo.getName();
        ResponseResult<CategoryVo> stResult = basicClient.findCourseById(st);
        CategoryVo stCategoryVo = stResult.getData();
        String stName = stCategoryVo.getName();
        coursePub.setStName(stName);
        coursePub.setMtName(mtName);
        coursePub.setTeachplan(JSON.toJSONString(teachplanVo));
        //查询老师
        LambdaQueryWrapper<CourseTeacher> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseTeacher::getCourseId, courseBaseId);
        CourseTeacher teacher = courseTeacherService.getOne(queryWrapper);
        coursePub.setTeachers(JSON.toJSONString(teacher));
        map.put("coursePub", coursePub);
        return map;
    }

    /**
     * 课程发布
     *
     * @param courseBaseId
     * @return
     */
    @Override
    @Transactional
    public ResponseResult publish(Long courseBaseId) throws IOException, TemplateException {
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        //查询课程是否审核通过
        String auditStatus = courseBase.getAuditStatus();
        if (!StrUtil.equals(auditStatus, CourseConstants.AUDIT_PASTED_STATUS)) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        Map map = this.preview(courseBaseId);
        CoursePub coursePub = (CoursePub) map.get("coursePub");
        coursePub.setCourseId(courseBaseId);
        this.save(coursePub);

        courseBase.setAuditStatus(CourseConstants.AUDIT_PUBLISHED_STATUS);
        courseBaseService.updateById(courseBase);
        //异步生成html
        pubPageService.uploadHtml(map, courseBaseId);
        //发送mq消息
        rabbitTemplate.convertAndSend("content-exchange","course.pub" , coursePub.getId());
        return ResponseResult.okResult();
    }

    /**
     * 已发布课程下架
     * @param courseId
     * @return
     */
    @Override
    public ResponseResult offlineById(Long courseId) throws ServerException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        CourseBase courseBase = courseBaseService.getById(courseId);
        //查询课程是否是已发布视频
        String auditStatus = courseBase.getAuditStatus();
        if (!StrUtil.equals(auditStatus, CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        this.removeById(courseId);

        //下架后课程修改为未提交
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);
        courseBaseService.updateById(courseBase);

        //异步删除html
        pubPageService.deleteHtml(courseId);
        //发送mq消息
        rabbitTemplate.convertAndSend("content-exchange","course.unpub" , courseId);
        return ResponseResult.okResult();
    }
}
